import { AfterViewInit, Directive, ElementRef, Input, NgZone, OnDestroy, Self } from '@angular/core';
import { DxDataGridComponent } from 'devextreme-angular/ui/data-grid';
import DataStore from 'devextreme/data/data_source';
import { Subscription } from 'rxjs';
import { BroadcastService } from '../../../core/service/broadcast.service';
@Directive({
  // tslint:disable-next-line:directive-selector
  selector: 'dx-data-grid'
})

export class BzDxDataGridDirective<B> implements AfterViewInit, OnDestroy {

  @Input() dataSource: DataStore | any;
  @Input() disabledRepaintCheck = false;

  pageSize = 0;
  private willRepaint = false;
  private subscription: Subscription;
  private _isFixed = false;
  private _timeout;

  constructor(
    private el: ElementRef,
    private ngZone: NgZone,
    private broadcastService: BroadcastService<B>,
    @Self() private dataGrid: DxDataGridComponent
  ) { }

  ngAfterViewInit(): void {
    this.ngZone.runOutsideAngular(() => {
      if (!this.disabledRepaintCheck) {
        window.addEventListener('resize', this.onResize);

        this.subscription = this.broadcastService.subscribe(<any>'ReuseOnInit', () => {
          if (!this.dataGrid.pager.visible && !this.dataGrid.paging.enabled) {
            return;
          }

          Promise.resolve().then(() => {
            const ele = this.el.nativeElement;
            if (this.willRepaint && ele.ownerDocument.contains(ele)) {
              this.repaint();
              this.willRepaint = false;
            }
          });
        });
      }

      this.dataGrid.pagingChange.subscribe((e) => {

        if (this.pageSize !== 0) {
          if (this.pageSize !== e.pageSize) {
            this.dataGrid.paging.pageIndex = 0;
          }
        }
        this.pageSize = e.pageSize;
        this.clearSurplusHeight();
      });
      this.subscription = this.broadcastService.subscribe(<any>'AsideCollapsed', () => {

        this.repaint();

      });
      if (this.dataGrid && this.dataGrid.columns) {
        this.listeningDataGrid();
      }
    });
  }
  onResize = () => {
    this.willRepaint = true;
  }

  ngOnDestroy(): void {
    window.removeEventListener('resize', this.onResize);
    this.subscription.unsubscribe();
  }

  /**
   * 清除表格最后一行高度，防止最后一页数据不满一页时高度被撑开
   */
  private clearSurplusHeight() {
    if (!this.dataSource) {
      return;
    }
    if (!this.dataGrid.pager.visible && !this.dataGrid.paging.enabled) {
      return;
    }
    if (!this.dataGrid.paging.pageIndex) {
      return;
    }
    const _nums = Math.ceil((this.dataSource._totalCount || this.dataSource.length) / this.dataGrid.paging.pageSize) - 1;
    const isLastIndex = _nums === (this.dataGrid.paging.pageIndex || 0) ? true : false;
    if (isLastIndex) {
      this.ngZone.runOutsideAngular(() => {
        setTimeout(() => {
          this.el.nativeElement.querySelectorAll('.dx-freespace-row').forEach((el: HTMLElement) => {
            el.style.height = '0';
          });
          // console.log('%c%s', 'background-color: #ff0000;color:#fff;', 'dx-data-grid ' + isLastIndex);
        }, 300);
      });
    }
  }

  /**
   * 监听表格部分事件（优化表格行对齐）
   * 在初始化时没有固定列的情况下不做重绘
   * 监听列变化并重绘
   *  */
  private listeningDataGrid() {
    this._isFixed = this.dataGrid.columns.some(i => i.fixed && i.fixed === true);
    if (this._isFixed) {
      this.ngZone.runOutsideAngular(() => {
        setTimeout(() => {
          this.dataGrid.columnsChange.subscribe(e => {
            // console.log('listeningDataGrid');
            this.repaint();
          });
          // masterDetail展开行时重回导致DataGrid闪烁
          // this.dataGrid.onContentReady.subscribe(e => {
          //   this.repaint();
          // });
        }, 1500);
      });
    }
  }

  /** 重绘 */
  private repaint() {
    if (this._timeout) {
      clearTimeout(this._timeout);
    }
    this._timeout = setTimeout(() => {
      this._timeout = null;
      // console.log('%c%s', 'background-color:#000;color:#fff;', ' repaint ');

      this.dataGrid.instance.repaint();
      this.clearSurplusHeight();
    }, 300);
  }
}
